package com.ruoyi.boat.service.impl;

import java.util.*;

import com.ruoyi.boat.aop.MyDataScope;
import com.ruoyi.boat.aop.SQLFilter;
import com.ruoyi.boat.utils.ObjectUtil;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import com.ruoyi.boat.mapper.StatisticMapper;
import com.ruoyi.boat.domain.Statistic;
import com.ruoyi.boat.service.IStatisticService;
import com.ruoyi.common.core.text.Convert;

/**
 * 统计Service业务层处理
 *
 * @author ruoyi
 * @date 2023-08-09
 */
@Service
public class StatisticServiceImpl implements IStatisticService {

    @Autowired
    ApplicationContext context;

    @Autowired
    private StatisticMapper statisticMapper;

    /**
     * 查询统计
     *
     * @param id 统计主键
     * @return 统计
     */
    @Override
    public Statistic selectStatisticById(Long id) {
        return statisticMapper.selectStatisticById(id);
    }

    /**
     * 查询统计列表
     *
     * @param statistic 统计
     * @return 统计
     */
    @Override
    @MyDataScope
    @SQLFilter
    public List<Statistic> selectStatisticList(Statistic statistic) {
        return statisticMapper.selectStatisticList(statistic);
    }

    /**
     * 统计数据
     *
     * @param statistic
     * @return
     */
    @Override
    @MyDataScope
    @SQLFilter
    public Statistic selectStatisticCalculated(Statistic statistic) {
        return statisticMapper.selectStatisticCalculated(statistic);
    }

    @Override
    public Statistic selectStatisticListOfToday(Statistic statistic) {
        String[] times = DateUtils.getBeginTimeAndEndTimeOfToday();
        statistic.setTime(null);
        statistic.getParams().put("beginTime", times[0]);
        statistic.getParams().put("endTime", times[1]);
        return context.getBean(this.getClass()).selectStatisticCalculated(statistic);
    }

    @Override
    public Statistic selectStatisticListOfThisWeek(Statistic statistic) {
        String[] times = DateUtils.getBeginTimeAndEndTimeOfThisWeek();
        statistic.setTime(null);
        statistic.getParams().put("beginTime", times[0]);
        statistic.getParams().put("endTime", times[1]);
        return context.getBean(this.getClass()).selectStatisticCalculated(statistic);
    }

    @Override
    public Statistic selectStatisticListOfThisMonth(Statistic statistic) {
        String[] times = DateUtils.getBeginTimeAndEndTimeOfThisMonth();
        statistic.setTime(null);
        statistic.getParams().put("beginTime", times[0]);
        statistic.getParams().put("endTime", times[1]);
        return context.getBean(this.getClass()).selectStatisticCalculated(statistic);
    }

    /**
     * 获取当前账号权限下所有艇 今日 本周 本月的 统计
     *
     * @return
     */
    @Override
    public Map<String, Statistic> selectTodayThisWeekThisMonthStatistic() {
        Statistic statistic = new Statistic();
        HashMap<String, Statistic> map = new HashMap<>();
        map.put("today", context.getBean(this.getClass()).selectStatisticListOfToday(statistic));
        map.put("week", context.getBean(this.getClass()).selectStatisticListOfThisWeek(statistic));
        map.put("month", context.getBean(this.getClass()).selectStatisticListOfThisMonth(statistic));
        return map;
    }

    /**
     * 新增统计
     *
     * @param statistic 统计
     * @return 结果
     */
    @Override
    public int insertStatistic(Statistic statistic) {
        return statisticMapper.insertStatistic(statistic);
    }

    /**
     * 收到消息后 新建Statistic
     * setBoatCode(xx), setTime(new Date())
     * setMsgReceive(1), setMsgAll(序列号)
     * 如果是stay 再setMsgStay(1), in的话 再setMsgStayIn(1)
     * 然后调用本方法
     * 如果存在则累加
     * 不存在就创建
     *
     * @param statistic
     * @return Integer
     */
    @Override
    synchronized public int insertOrUpdate(Statistic statistic) {
        if (Objects.isNull(statistic.getBoatCode())) throw new Error("Boat code should be specified");
        if (Objects.isNull(statistic.getTime())) throw new Error("Time should be specified.");

        statistic.getTime().setHours(0);
        statistic.getTime().setMinutes(0);
        statistic.getTime().setSeconds(0);

        // check if exist
        List<Statistic> statistics = this.selectStatisticList(statistic);
        if (statistics.size() != 0) {
            // exist
            Statistic statisticInDB = statistics.get(0);
            if (!Objects.isNull(statistic.getMsgAll()))
                statisticInDB.setMsgAll(statistic.getMsgAll());
            if (!Objects.isNull(statistic.getMsgReceived())) {
                Integer msgReceived = statistic.getMsgReceived() + ObjectUtil.getInteger(statisticInDB.getMsgReceived(), 0);
                statisticInDB.setMsgReceived(msgReceived);
            }
            if (!Objects.isNull(statistic.getMsgStay())) {
                Integer msgStay = statistic.getMsgStay() + ObjectUtil.getInteger(statisticInDB.getMsgStay(), 0);
                statisticInDB.setMsgStay(msgStay);
            }
            if (!Objects.isNull(statistic.getMsgStayIn())) {
                Integer msgStayIn = statistic.getMsgStayIn() + ObjectUtil.getInteger(statisticInDB.getMsgStayIn(), 0);
                statisticInDB.setMsgStayIn(msgStayIn);
            }
            return this.updateStatistic(statisticInDB);
        } else {
            // not exist
            return this.insertStatistic(statistic);
        }
    }

    /**
     * 修改统计
     *
     * @param statistic 统计
     * @return 结果
     */
    @Override
    public int updateStatistic(Statistic statistic) {
        return statisticMapper.updateStatistic(statistic);
    }

    /**
     * 修改统计
     *
     * @param statistic 统计
     * @return 结果
     */
    @Override
    public int updateStatisticByBoatCodeAndTime(Statistic statistic) {
        if (statistic.getBoatCode() == null || statistic.getTime() == null)
            throw new RuntimeException("boatCode or time should not be null");
        return statisticMapper.updateStatisticByBoatCodeAndTime(statistic);
    }

    /**
     * 批量删除统计
     *
     * @param ids 需要删除的统计主键
     * @return 结果
     */
    @Override
    public int deleteStatisticByIds(String ids) {
        return statisticMapper.deleteStatisticByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除统计信息
     *
     * @param id 统计主键
     * @return 结果
     */
    @Override
    public int deleteStatisticById(Long id) {
        return statisticMapper.deleteStatisticById(id);
    }
}
